#include /* Java Native Interface headers */ #include "Quadrature.h" /* Auto-generated header created by javah -jni */ #include #include #include /* NAG C Library headers */ #include /* Nasty global variables; they are global because they are required by the function evaluator intFun, but come from Java via the native interface routine Java_Quadrature_d01ajc. */ JNIEnv *globalJavaEnv; jobject globalJavaObject; jmethodID globalMid; /* This is the interface to the Java function which is to be integrated. */ double intFun(double x) { jdouble res; /* Here's where we call back to the user's function in the Java code */ res = (*globalJavaEnv)->CallDoubleMethod(globalJavaEnv, globalJavaObject, globalMid, (jdouble)x); return (double)res; } /* Our C definition of the function d01ajc declared in Quadrature.java. The return value is an error code. Other results are returned via direct JNI access to Java object member variables. */ JNIEXPORT jint JNICALL Java_Quadrature_d01ajc(JNIEnv *env, jobject obj, jstring funName, jdouble a, jdouble b, jdouble epsabs, jdouble epsrel, jint max_num_subint) { static NagError fail; Nag_QuadProgress qp; double result, abserr; jclass cls; const char *functionName; jfieldID fid; int retVal; fail.print = FALSE; /* Copy the Java env pointers to global space so that intFun can access them. */ globalJavaEnv = env; globalJavaObject = obj; /* Get hold of the name of the user's Java evaluation function. */ functionName = (*env)->GetStringUTFChars(env, funName, 0); /* Now we have the Java evaluation function name we can use it to get hold of a handle (method ID) to the function. Once more, the method ID is stored globally so that intFun can use it. Note that the Java function signature must be "(D)D" (i.e. function with double argument, returning double). */ cls = (*env)->GetObjectClass(env, obj); globalMid = (*env)->GetMethodID(env, cls, functionName, "(D)D"); /* Free up the Java string argument so we don't leak memory. */ (*env)->ReleaseStringUTFChars(env, funName, functionName); if (globalMid == 0) /* Cannot find method "functionName" with signature (D)D */ return -1; else { /* Now call the function we're interested in from the NAG C Library. intFun is the function that we want to integrate. */ d01ajc(intFun, (double)a, (double)b, (double)epsabs, (double)epsrel, (Integer)max_num_subint, &result, &abserr, &qp, &fail); if (fail.code == 0) { /* Put the results back to Java. */ /* Get the ID of the Java Quadrature class member variable "result" (which is of type double, hence the "D" signature). */ fid = (*env)->GetFieldID(env, cls, "result", "D"); /* Set the result value via the ID */ (*env)->SetDoubleField(env, obj, fid, result); /* Repeat for other results */ fid = (*env)->GetFieldID(env, cls, "abserr", "D"); (*env)->SetDoubleField(env, obj, fid, abserr); fid = (*env)->GetFieldID(env, cls, "nFun", "I"); (*env)->SetIntField(env, obj, fid, qp.fun_count); fid = (*env)->GetFieldID(env, cls, "nSubInt", "I"); (*env)->SetIntField(env, obj, fid, qp.num_subint); } } /* Return any fail code that the nagc.dll function d01ajc returned. */ return fail.code; }